#ifndef ILLRT_NUMERIC_H_
#define ILLRT_NUMERIC_H_

#include <ilrt/Type.h>
#include <ilrt/Allocator.h>

namespace ilrt{
	class NumericType : public BasicType
	{
	public:
	public:
		NumericType(Runtime & runtime) :
			BasicType(runtime)
		{

		}
		virtual ~NumericType(){

		}
		virtual void destroyType(Runtime & runtime){
		}
	};

	class BooleanType : public NumericType {
	public:
		BooleanType(Runtime & runtime) : NumericType(runtime)
		{

		}
		virtual BasicTypedPointer _create(){
			return BasicPointer::False;
		}
		virtual void _destroy(BasicPointer value){

		}
		virtual const char * name(){
			return "Boolean";
		}
	};
	class IndexType : public NumericType  {
	public:
		typedef Allocator::PoolAllocator<size_t> AllocatorType;
	protected:
		AllocatorType allocator_;
	public:
		IndexType(Runtime & runtime) :
			NumericType(runtime),
			allocator_(this, "")
		{

		}
		AllocatorType & allocator(){return allocator_;}
		virtual BasicTypedPointer _create()
		{
			return BasicTypedPointer(&allocator_.create(), *this);
		}
		virtual void _destroy(BasicPointer value)
		{
			illib::MemoryTracker::tracker().release(value._value());
		}
		virtual const char * name(){
			return "Index";
		}
	};
	class UnsignedInt8Type : public NumericType  {
	public:
		UnsignedInt8Type(Runtime & runtime) : NumericType(runtime)
		{

		}
		virtual BasicTypedPointer _create()
		{
			return BasicTypedPointer::UnsignedInt8(0);
		}
		virtual void _destroy(BasicPointer value)
		{
		}
		virtual const char * name(){
			return "UnsignedInt8";
		}
	};
	class UnsignedInt16Type : public NumericType  {
	public:
		typedef Allocator::PoolAllocator<uint16_t> AllocatorType;
	protected:
		AllocatorType allocator_;
	public:
		UnsignedInt16Type(Runtime & runtime) :
			NumericType(runtime),
			allocator_(this, "")
		{

		}
		AllocatorType & allocator(){return allocator_;}
		virtual BasicTypedPointer _create()
		{
			return BasicTypedPointer(&allocator_.create(), *this);
		}
		virtual void _destroy(BasicPointer value)
		{
			illib::MemoryTracker::tracker().release(value._value());
		}
		virtual const char * name(){
			return "UnsignedInt16";
		}
	};
	class UnsignedInt32Type : public NumericType  {
	public:
		typedef Allocator::PoolAllocator<uint32_t> AllocatorType;
	protected:
		AllocatorType allocator_;
	public:
		UnsignedInt32Type(Runtime & runtime) :
			NumericType(runtime),
			allocator_(this, "")
		{

		}
		AllocatorType & allocator(){return allocator_;}
		virtual BasicTypedPointer _create()
		{
			return BasicTypedPointer(&allocator_.create(), *this);
		}
		virtual void _destroy(BasicPointer value)
		{
			illib::MemoryTracker::tracker().release(value._value());
		}
		virtual const char * name(){
			return "UnsignedInt32";
		}
	};
	class UnsignedInt64Type : public NumericType  {
	public:
		typedef Allocator::PoolAllocator<uint64_t> AllocatorType;
	protected:
		AllocatorType allocator_;
	public:
		UnsignedInt64Type(Runtime & runtime) :
			NumericType(runtime),
			allocator_(this, "")
		{

		}
		AllocatorType & allocator(){return allocator_;}
		virtual BasicTypedPointer _create()
		{
			return BasicTypedPointer::None;
		}
		virtual void _destroy(BasicPointer value)
		{
			illib::MemoryTracker::tracker().release(value._value());
		}
		virtual const char * name(){
			return "UnsignedInt64";
		}
	};
	class SignedInt8Type : public NumericType  {
	public:
		SignedInt8Type(Runtime & runtime) : NumericType(runtime)
		{

		}
		virtual BasicTypedPointer _create()
		{
			return BasicTypedPointer::SignedInt8(0);
		}
		virtual void _destroy(BasicPointer value)
		{
		}
		virtual const char * name(){
			return "SignedInt8";
		}
	};
	class SignedInt16Type : public NumericType {
	public:
		typedef Allocator::PoolAllocator<int16_t> AllocatorType;
	protected:
		AllocatorType allocator_;
	public:
		SignedInt16Type(Runtime & runtime) :
			NumericType(runtime),
			allocator_(this, "")
		{

		}
		AllocatorType & allocator(){return allocator_;}
		virtual BasicTypedPointer _create()
		{
			return BasicTypedPointer(&allocator_.create(), *this);
		}
		virtual void _destroy(BasicPointer value)
		{
			illib::MemoryTracker::tracker().release(value._value());
		}
		virtual const char * name(){
			return "SignedInt16";
		}
	};
	class SignedInt32Type : public NumericType {
	public:
		typedef Allocator::PoolAllocator<int32_t> AllocatorType;
	protected:
		AllocatorType allocator_;
	public:
		SignedInt32Type(Runtime & runtime) :
			NumericType(runtime),
			allocator_(this, "")
		{

		}
		AllocatorType & allocator(){return allocator_;}
		virtual BasicTypedPointer _create()
		{
			return BasicTypedPointer(&allocator_.create(), *this);
		}
		virtual void _destroy(BasicPointer value)
		{
			illib::MemoryTracker::tracker().release(value._value());
		}
		virtual const char * name(){
			return "SignedInt32";
		}
	};
	class SignedInt64Type : public NumericType {
	public:
		typedef Allocator::PoolAllocator<int64_t> AllocatorType;
	protected:
		AllocatorType allocator_;
	public:
		SignedInt64Type(Runtime & runtime) :
			NumericType(runtime),
			allocator_(this, "")
		{

		}
		AllocatorType & allocator(){return allocator_;}
		virtual BasicTypedPointer _create()
		{
			return BasicTypedPointer(&allocator_.create(), *this);
		}
		virtual void _destroy(BasicPointer value)
		{
			illib::MemoryTracker::tracker().release(value._value());
		}
		virtual const char * name(){
			return "SignedInt64";
		}
	};
	class Float32Type : public NumericType {
	public:
		typedef Allocator::PoolAllocator<float> AllocatorType;
	protected:
		AllocatorType allocator_;
	public:
		Float32Type(Runtime & runtime) :
			NumericType(runtime),
			allocator_(this, "")
		{

		}
		AllocatorType & allocator(){return allocator_;}
		virtual BasicTypedPointer _create()
		{
			return BasicTypedPointer(&allocator_.create(), *this);
		}
		virtual void _destroy(BasicPointer value)
		{
			illib::MemoryTracker::tracker().release(value._value());
		}
		virtual const char * name(){
			return "Float32";
		}
	};
	class Float64Type : public NumericType {
	public:
		typedef Allocator::PoolAllocator<double> AllocatorType;
	protected:
		AllocatorType allocator_;
	public:
		Float64Type(Runtime & runtime) :
			NumericType(runtime),
			allocator_(this, "")
		{

		}
		AllocatorType & allocator(){return allocator_;}
		virtual BasicTypedPointer _create()
		{
			return BasicTypedPointer(&allocator_.create(), *this);
		}
		virtual void _destroy(BasicPointer value)
		{
			illib::MemoryTracker::tracker().release(value._value());
		}
		virtual const char * name(){
			return "Float64";
		}
	};
}

#endif
